package testing;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

import dse.Experiment;
import dse.DseException;
import dse.ExperimentConfiguration;
import dse.ExperimentRecorder;
import dse.ExperimentResults;
import dse.Modules;
import dse.PropertiesUtil;
import dse.StandardExperimentRecorder;

public class BasicTest extends Experiment {

	public BasicTest (
			ExperimentConfiguration config, 
			Modules modules
			)
	{
		super(config, modules);
	}

	protected void performExtraSetup (
			ExperimentRecorder recorder
			)
	{
		/**/
	}
	

	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void runTest (Class testType, Properties props)
	throws NoSuchMethodException, DseException, InstantiationException,  
		IllegalAccessException, InvocationTargetException
	{
		ExperimentConfiguration conf = new ExperimentConfiguration(props);
		Modules modules = new Modules (conf, props);
	
		Constructor<BasicTest> cons = testType.getConstructor(
				new Class[]{ExperimentConfiguration.class, Modules.class}
				);
		
		BasicTest test = cons.newInstance(new Object[]{conf, modules});
		
		ExperimentRecorder recorder = new StandardExperimentRecorder(
				PropertiesUtil.collectSubset(props, "recorder.")				
				);
		
		System.out.println("STARTING EXPERIMENT");
		long startTime = System.currentTimeMillis();

		test.startExperiment(recorder);
		
		
		test.performExtraSetup(recorder);

		
		for (int a = 0; a < conf.getNumberOfPeriodsToRun(); a++) {
			System.out.println("PERIOD #" + (a+1));
			
			test.runPeriod(recorder);
		}
		long endTime = System.currentTimeMillis();
		System.out.println("DONE");
		System.out.println("");
		System.out.println("");
		
		
		ExperimentResults results = recorder.getResults();
		System.out.println(results.toString(
				test.config.getTestType(),
				test.network, test.dataObjects,
				((double)(endTime - startTime))/1000
				));
	}
}
